package com.lwc.cfdns.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lwc.cfdns.common.Assert;
import com.lwc.cfdns.constants.Constants;
import com.lwc.cfdns.enums.ResultCode;
import com.lwc.cfdns.enums.StatusEnum;
import com.lwc.cfdns.exception.BadException;
import com.lwc.cfdns.pojo.bo.system.DictDataBO;
import com.lwc.cfdns.pojo.dto.system.DictDataDTO;
import com.lwc.cfdns.pojo.entity.SystemDict;
import com.lwc.cfdns.pojo.entity.SystemDictData;
import com.lwc.cfdns.pojo.vo.system.DictDataVO;
import com.lwc.cfdns.service.SystemDictDataService;
import com.lwc.cfdns.mapper.SystemDictDataMapper;
import com.lwc.cfdns.utils.ConvertUtils;
import com.lwc.cfdns.utils.RedisUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author spring
 * @description 针对表【cfdns_system_dict_data(字典数据表)】的数据库操作Service实现
 * @createDate 2023-05-28 20:44:32
 */
@Service
public class SystemDictDataServiceImpl extends ServiceImpl<SystemDictDataMapper, SystemDictData>
        implements SystemDictDataService {
    @Autowired
    private SystemDictServiceImpl systemDictService;
    @Resource
    private RedisUtils redisUtils;

    /**
     * 创建
     *
     * @param dictDataDTO
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 12:07:27
     */
    @Override
    public Map<String, Object> create(DictDataDTO dictDataDTO) {
        SystemDict systemDict = systemDictService.getOne(new LambdaQueryWrapper<SystemDict>().eq(SystemDict::getMarks, dictDataDTO.getMarks()));
        Assert.notNull(systemDict, ResultCode.NOT_DATA_FOUNT);
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<SystemDictData>().eq(SystemDictData::getMarks, dictDataDTO.getMarks()).eq(SystemDictData::getValue, dictDataDTO.getValue()));
        if (count > 0) {
            throw new BadException("字典键值已存在,不可重复");
        }
        SystemDictData systemDictData = new SystemDictData();
        BeanUtils.copyProperties(dictDataDTO, systemDictData);
        this.baseMapper.insert(systemDictData);
        Map<String, Object> map = new HashMap<>();
        map.put("id", systemDictData.getId());
        return map;
    }

    /**
     * 修改
     *
     * @param dictDataDTO
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 12:07:48
     */
    @Override
    public Map<String, Object> update(DictDataDTO dictDataDTO) {
        SystemDict systemDict = systemDictService.getOne(new LambdaQueryWrapper<SystemDict>().eq(SystemDict::getMarks, dictDataDTO.getMarks()));
        Assert.notNull(systemDict, ResultCode.NOT_DATA_FOUNT);
        Long count = this.baseMapper.selectCount(new LambdaQueryWrapper<SystemDictData>()
                .eq(SystemDictData::getMarks, dictDataDTO.getMarks())
                .eq(SystemDictData::getValue, dictDataDTO.getValue())
                .ne(SystemDictData::getId, dictDataDTO.getId())
        );
        if (count > 0) {
            throw new BadException("字典键值已存在,不可重复");
        }
        SystemDictData systemDictData = this.baseMapper.selectById(dictDataDTO.getId());
        Assert.notNull(systemDictData, ResultCode.NOT_DATA_FOUNT);
        BeanUtils.copyProperties(dictDataDTO, systemDictData);
        int i = this.baseMapper.updateById(systemDictData);
        Map<String, Object> map = new HashMap<>();
        map.put("result", i);
        return map;
    }

    /**
     * 详情
     *
     * @param id
     * @return DictDataVO
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 12:10:01
     */
    @Override
    public DictDataVO view(Long id) {
        SystemDictData systemDictData = this.baseMapper.selectById(id);
        Assert.notNull(systemDictData, ResultCode.NOT_DATA_FOUNT);
        DictDataVO dictDataVO = new DictDataVO();
        BeanUtils.copyProperties(systemDictData, dictDataVO);
        return dictDataVO;
    }

    /**
     * 删除
     *
     * @param ids
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 12:11:42
     */
    @Override
    public Map<String, Object> delete(String ids) {
        Integer i;
        if (ids.contains(",")) {
            i = this.baseMapper.delete(new LambdaQueryWrapper<SystemDictData>().in(SystemDictData::getId, ConvertUtils.toLongArray(ids)));
        } else {
            i = this.baseMapper.deleteById(ConvertUtils.toLong(ids));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("result", i);
        return map;
    }

    /**
     * 列表
     *
     * @param dictDataBO
     * @return IPage<SystemDictData>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 12:17:12
     */
    @Override
    public IPage<SystemDictData> lists(DictDataBO dictDataBO) {
        Page<SystemDictData> page = this.baseMapper.selectPage(dictDataBO.toPage(), dictDataBO.toQueryWrapper());
        // 转化成VO输出
        page.convert(s -> {
            DictDataVO vo = new DictDataVO();
            BeanUtils.copyProperties(s, vo);
            return vo;
        });

        return page;
    }

    /**
     * 根据标识查询字典数据
     * 没有缓存自动缓存，有缓存读取缓存
     *
     * @param marks
     * @return List<DictDataVO>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/29 15:52:38
     */
    @Override
    public List<DictDataVO> cacheOfMarks(String marks) {
        List<DictDataVO> cache = (List<DictDataVO>) redisUtils.get(Constants.dictPrefix + marks);
        if (cache == null) {
            cache = new ArrayList<>();
            //查库生成缓存
            List<SystemDictData> systemDictDatas = this.baseMapper.selectList(new LambdaQueryWrapper<SystemDictData>().eq(SystemDictData::getMarks, marks).eq(SystemDictData::getStatus, StatusEnum.NORMAL.getCode()));
            for (SystemDictData systemDictData : systemDictDatas) {
                DictDataVO dictDataVO = new DictDataVO();
                BeanUtils.copyProperties(systemDictData, dictDataVO);
                cache.add(dictDataVO);
            }
            redisUtils.set(Constants.dictPrefix + marks, cache);
        }
        return cache;
    }
}




